package com.zmn.oms.services.impl.report;

import com.alibaba.fastjson.JSON;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.oms.business.impl.base.AbstractListEsQueryServiceImpl;
import com.zmn.oms.business.interfaces.es.OrderWorkEsBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.model.entity.report.ComplaintReportOrderCount;
import com.zmn.oms.model.entity.report.ComplaintReportQuery;
import com.zmn.oms.model.entity.report.EsComplainReportQuery;
import com.zmn.oms.services.interfaces.report.ReportUmsComplaintService;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedValueCount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 类描述: UMS-投诉报表总单量业务实现
 *
 * @author mujunlin
 * @date 2019/05/06 11:31
 */
@Service
public class ReportUmsComplaintServiceImpl extends AbstractListEsQueryServiceImpl implements ReportUmsComplaintService {

    private Logger logger = LoggerFactory.getLogger(ReportUmsComplaintServiceImpl.class);

    @Autowired
    OrderWorkEsBService orderWorkEsBService;

    @Override
    public List<ComplaintReportOrderCount> listByQuery(ComplaintReportQuery query) {

        // 构建ES查询条件
        EsComplainReportQuery esQuery = this.buildComplainEsQuery(query);
        esQuery.setPlatWork(GlobalConsts.PLAT_MARK_ZMN);
        NativeSearchQuery searchQuery = super.builderSearchQuery(esQuery);
        searchQuery.setPageable(PageRequest.of(0, 1));

        // 按公司ID分组
        String groupFieldCompany = "companyId";
        // 按城市ID分组
        String groupFieldCity = "cityId";
        // 构建ES查询对象
        TermsAggregationBuilder cityGroupAggregation = AggregationBuilders
                .terms(groupFieldCity).field(groupFieldCity).size(10000);
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders
                .terms(groupFieldCompany).field(groupFieldCompany).size(10000)
                .subAggregation(cityGroupAggregation);
        // 按订单ID统计
        cityGroupAggregation.subAggregation(AggregationBuilders.count("orderId").field("orderId"));
        // 统计渠道为58的订单
        cityGroupAggregation.subAggregation(
                AggregationBuilders.filter("channel_filter", QueryBuilders.boolQuery()
                        .should(QueryBuilders.termQuery("channelId", 1322))
                        .should(QueryBuilders.termQuery("channelId", 1511))
                ).subAggregation(AggregationBuilders.count("orderId_count").field("orderId")));
        // 按总订单降序排列
        cityGroupAggregation.order(BucketOrder.aggregation("orderId", false)).size(10000);
        // 查询条件添加聚合
        searchQuery.addAggregation(cityGroupAggregation);
        // 按总订单降序排列
        cityGroupAggregation.order(BucketOrder.aggregation("orderId", false)).size(10000);
        searchQuery.addAggregation(termsAggregationBuilder);
        Aggregations query1 = orderWorkEsBService.getAggregationsByQuery(searchQuery);
        ParsedLongTerms terms = query1.get(groupFieldCompany);
        List<? extends Terms.Bucket> buckets = terms.getBuckets();
        // 构建查询结果
        ArrayList<ComplaintReportOrderCount> orderCountVOS = new ArrayList<>();
        if (CollectionUtils.isEmpty(buckets)) {
            return orderCountVOS;
        }
        buckets.forEach(bucket -> {
            // 公司ID
            int companyId = bucket.getKeyAsNumber().intValue();
            ParsedLongTerms terms1 = bucket.getAggregations().get(groupFieldCity);
            List<? extends Terms.Bucket> buckets1 = terms1.getBuckets();
            buckets1.forEach(bucket1 -> {
                Map<String, Aggregation> bucketMap = bucket1.getAggregations().asMap();
                // 城市ID
                int cityId = bucket1.getKeyAsNumber().intValue();
                // 总单量
                Long totalOrder = ((ParsedValueCount) bucketMap.get("orderId")).getValue();
                // 58单量
                ParsedValueCount valueCount = (ParsedValueCount) ((ParsedFilter) bucketMap.get("channel_filter"))
                        .getAggregations().asMap().get("orderId_count");
                long order58Count = valueCount.getValue();
                ComplaintReportOrderCount orderCountVO = new ComplaintReportOrderCount();
                orderCountVO.setCompanyId(companyId);
                orderCountVO.setCityId(cityId);
                orderCountVO.setOrderCount(totalOrder.intValue());
                orderCountVO.setOrder58Count((int)order58Count);
                orderCountVOS.add(orderCountVO);
            });
        });

        // 计算总计行
        ComplaintReportOrderCount totalCount = new ComplaintReportOrderCount();
        totalCount.setCompanyId(100);
        totalCount.setCityId(100);
        ComplaintReportOrderCount orderCountTotoalVO = orderCountVOS.stream().reduce(totalCount, (sum, vo) -> {
            // 总单量
            Integer totalOrder = sum.getOrderCount();
            sum.setOrderCount(Optional.ofNullable(totalOrder).orElse(0) + vo.getOrderCount());
            // 58单量
            Integer order58Count = sum.getOrder58Count();
            sum.setOrder58Count(Optional.ofNullable(order58Count).orElse(0) + vo.getOrder58Count());
            return sum;
        });
        orderCountVOS.add(orderCountTotoalVO);

        logger.info("投诉报表总单orderCountVOS[{}]", JSON.toJSON(orderCountVOS));
        return orderCountVOS;
    }

    /**
     * 构建ES查询条件
     *
     * @param query 投诉报表查询条件
     * @return 投诉报表ES查询条件
     */
    private EsComplainReportQuery buildComplainEsQuery(ComplaintReportQuery query) {
        EsComplainReportQuery esQuery = new EsComplainReportQuery();
        esQuery.setType(OrderConsts.ORDER_TYPE_NEW);
        esQuery.setDuplicate(GlobalConsts.NO);
        if (query.getCompanyId() != null) {
            esQuery.setCompanyId(query.getCompanyId());
        }
        // 城市ID未选择
        if (CollectionUtils.isEmpty(query.getCityIdList())) {
            esQuery.setCityId(null);
        } else {
            esQuery.setCityId(query.getCityIdList());
        }
        // 渠道ID未选择
        if (CollectionUtils.isEmpty(query.getChannelIdList())) {
            esQuery.setChannelId(null);
        } else {
            esQuery.setChannelId(query.getChannelIdList());
        }
        // 无时间范围:默认统计当日
        if (Objects.isNull(query.getStartTime()) && Objects.isNull(query.getEndTime())) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            query.setStartTime(format.format(new Date()));
            query.setEndTime(format.format(new Date()));
        }
        esQuery.setQueryTime(query.getStartTime() + "," + query.getEndTime());
        esQuery.setDeptId(query.getDeptId());
        esQuery.setStaffId(query.getStaffId());
        return esQuery;
    }
}
